﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Script.Serialization;

namespace FlowBasis.Json
{
    public class JsonSerializationService : IJsonSerializationService
    {
        private const int DefaultMaxJsonLength = 100000000;
        private const int DefaultRecursionLimit = 250;

        private Func<IJObjectRootMapper> rootMapperFactory;
        private int maxJsonLength = DefaultMaxJsonLength;
        private int recursionLimit = DefaultRecursionLimit;

        public JsonSerializationService(Func<IJObjectRootMapper> rootMapperFactory)
        {
            this.rootMapperFactory = rootMapperFactory;
        }

        public int MaxJsonLength
        {
            get { return this.maxJsonLength; }
            set { this.maxJsonLength = value; }
        }

        public int RecursionLimit
        {
            get { return this.recursionLimit; }
            set { this.recursionLimit = value; }
        }

        public string Stringify(object value)
        {
            var rootMapper = this.rootMapperFactory();
            object jObject = rootMapper.ToJObject(value);

            JavaScriptSerializer serializer = new JavaScriptSerializer();
            serializer.MaxJsonLength = this.maxJsonLength;
            serializer.RecursionLimit = this.recursionLimit;
            string json = serializer.Serialize(jObject);
            return json;
        }

        public object Parse(string json)
        {
            object jObject = JObject.Parse(json);
            return jObject;
        }

        public object Parse(string json, Type targetType)
        {
            object jObject = JObject.Parse(json);

            var rootMapper = this.rootMapperFactory();
            object value = rootMapper.FromJObject(jObject, targetType);
            return value;
        }

        public T Parse<T>(string json)
        {
            return (T)Parse(json, typeof(T));
        }
    }
}
